package com.acme.bankapp.client;

import java.io.Console;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import com.acme.bankapp.client.validator.Validator;
import com.acme.bankapp.client.validator.ValidatorFactory;

public class BankClient {

    private static final int DEFAULT_SERVER_PORT = 14519;
    private static final String DEFAULT_SERVER_IP = "127.0.0.1";

    private Socket requestSocket;

    private ObjectOutputStream out;

    private ObjectInputStream in;
    private String serverIP = DEFAULT_SERVER_IP;
    private int serverPort = DEFAULT_SERVER_PORT;
    private Console cliInput = System.console();

    public String getServerIP() {
	return serverIP;
    }

    public int getServerPort() {
	return serverPort;
    }

    public void setServerIP(final String serverIP) {
	this.serverIP = serverIP;
    }

    public void setServerPort(final int serverPort) {
	this.serverPort = serverPort;
    }

    void run() {
	String userMessage = null;
	Validator<String> cmdValidator = ValidatorFactory.createCmdSyntaxValidator();
	Validator<String> byeCmdValidator = ValidatorFactory.createByeCmdValidator();
	try {
	    requestSocket = new Socket(serverIP, serverPort);
	    System.out.println("Connected to " + serverIP + " in port "
		    + serverPort + ".");
	    out = new ObjectOutputStream(requestSocket.getOutputStream());
	    out.flush();
	    in = new ObjectInputStream(requestSocket.getInputStream());
	    do {
		try {
		    userMessage = cliInput.readLine();
		    if (cmdValidator.validate(userMessage)) {
			sendMessage(userMessage);
			System.out.println("Waiting for server's answer.");
			String serverMessage = (String) in.readObject();
			System.out.println("server>" + serverMessage);
		    } else {
			System.out.println("Unknown command.");
		    }
		} catch (ClassNotFoundException classNot) {
		    System.err.println("data received in unknown format");
		}
	    } while (!byeCmdValidator.validate(userMessage));
	} catch (UnknownHostException e) {
	    System.err.println("You are trying to connect to an unknown host!");
	} catch (EOFException e) {
	    System.out.println("Session was closed by server.");
	    System.exit(0);
	} catch (IOException e) {
	    e.printStackTrace();
	} finally {
	    try {
		in.close();
		out.close();
		requestSocket.close();
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	}
    }

    void sendMessage(final String msg) {
	try {
	    out.writeObject(msg);
	    out.flush();
	    System.out.println("client>" + msg);
	} catch (IOException e) {
	    e.printStackTrace();
	}
    }
}
